/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { JSONSerializer } from './ans1/serializer-json.js';
import { Universal } from './ans1/types.js';
import { JSONDeserializer } from './ans1/deserializer-json.js';
import { DERSerializer } from './ans1der/der_serializer.js';
import { DERDeserializer } from './ans1der/der_deserializer.js';
import {
    arrayBufferToString,
    bufferToHexCodes,
    checkBufferParams,
    fromBase64,
    getParametersValue,
    getUTCDate,
    isEqualBuffer,
    nearestPowerOf2,
    padNumber,
    stringToArrayBuffer,
    toBase64,
    utilConcatBuf,
    utilConcatView,
    utilFromBase,
    utilToBase
} from './utils.js';

import * as asn1js from './ans1/asn1.js';
import { ONE_KB, TEN_kB, ONE_MB, ONE_KB_NUMBER_STRING, Base64, buffer} from './data.js';
import { Buffer } from './buffer/index.js';

function Sequence_TEST() {
    let sequence;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        sequence = new Universal.Sequence([
            new Universal.Integer(-Number.MAX_SAFE_INTEGER), 
            new Universal.Integer(Number.MAX_SAFE_INTEGER),
            new Universal.Null(), 
            new Universal.Bool(true), 
            new Universal.Bool(false),
            new Universal.PrintableString(TEN_kB), 
            new Universal.PrintableString('an underwater universe where sunlight barely penetrates and darkness reigns supreme. '),
        ]);
    }
    let endTime = Date.now();

    if(sequence.content.length !== 7){
        throw new Error('asn-one_Universal.Sequence Error')
    }
    print(`asn-one_Universal.Sequence: ${endTime - startTime} ms`);
}

function Integer_TEST() {
    let sequence
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        sequence = new Universal.Integer(Number.MAX_SAFE_INTEGER) // 9007199254740991
    }
    let endTime = Date.now()

    if(sequence.content !== 9007199254740991){
        throw new Error('asn-one_Universal.Integer Error')
    }
    print(`asn-one_Universal.Integer: ${endTime - startTime} ms`)
}

function Null_TEST() {
    let sequence
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        sequence = new Universal.Null()
    }
    let endTime = Date.now()

    if(sequence.constructor.name !== 'Null'){
        throw new Error('asn-one_Universal.Null Error')
    }
    print(`asn-one_Universal.Null: ${endTime - startTime} ms`)
}

function Bool_TEST() {
    let asn1Object
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        asn1Object = new Universal.Bool(true);
    }
    let endTime = Date.now();

    if(asn1Object.content !== true){
        throw new Error('asn-one_Bool Error')
    }
    print(`asn-one_Bool: ${endTime - startTime} ms`);
}

function PrintableString_TEST() {
    let asn1Object
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        asn1Object = new Universal.PrintableString(ONE_MB)
    }
    let endTime = Date.now()

    if(asn1Object.content !== ONE_MB){
        throw new Error('asn-one_PrintableString Error')
    }
    print(`asn-one_PrintableString: ${endTime - startTime} ms`)
}

function JSONSerializer_TEST() {
    let sequence = new Universal.Sequence([
        new Universal.Integer(-Number.MAX_SAFE_INTEGER), 
        new Universal.Integer(Number.MAX_SAFE_INTEGER),
        new Universal.Null(), 
        new Universal.Bool(true), 
        new Universal.Bool(false),
        new Universal.PrintableString(TEN_kB), 
        new Universal.PrintableString('an underwater universe where sunlight barely penetrates and darkness reigns supreme.'),
    ]);
    let transmitJson;
    let serialize= new JSONSerializer();

    let startTime1 = Date.now()
    for (let i = 0; i < 10000; i++) {
        transmitJson = serialize(sequence);
    }
    let endTime1 = Date.now()

    if(transmitJson.type !== 'sequence'){
        throw new Error('asn-one_JSONSerializer Error')
    }
    print(`asn-one_JSONSerializer: ${endTime1 - startTime1} ms`)
}

function JSONDeserializer_TEST() {
    let sequence = new Universal.Sequence([
        new Universal.Integer(-Number.MAX_SAFE_INTEGER), 
        new Universal.Integer(Number.MAX_SAFE_INTEGER),
        new Universal.Null(), 
        new Universal.Bool(true), 
        new Universal.Bool(false),
        new Universal.PrintableString(TEN_kB), 
        new Universal.PrintableString('an underwater universe where sunlight barely penetrates and darkness reigns supreme.'),
        new Universal.Sequence([
            new Universal.Integer(Number.MAX_SAFE_INTEGER),
            new Universal.PrintableString('nested sequence')
        ]),
    ]);

    let serialize= new JSONSerializer();
    let transmitJson = serialize(sequence);
    const deserialize = new JSONDeserializer();

    // 反序列化数据
    let asn1ObjectModel;
    let startTime2 = Date.now()
    for (let i = 0; i < 100; i++) {
        asn1ObjectModel = deserialize(transmitJson);
    }
    let endTime2 = Date.now()

    if(asn1ObjectModel.content.length !== 8){
        throw new Error('asn-one_JSONDeserializer Error')
    }
    print(`asn-one_JSONDeserializer: ${endTime2 - startTime2} ms`)
}

function DERSerializer_TEST() {
    const asn1Sequence = new Universal.Sequence([
        new Universal.Integer(2024),
        new Universal.Null(), 
        new Universal.PrintableString(TEN_kB), 
        new Universal.PrintableString('an underwater universe where sunlight barely penetrates and darkness reigns supreme.'),
    ]);

    let bufferContainingDEREncodedASN1;
    
    const serialize1 = new DERSerializer(); 

    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        bufferContainingDEREncodedASN1 = serialize1(asn1Sequence);
    }
    let endTime = Date.now()

    if(Buffer.isBuffer(bufferContainingDEREncodedASN1) !== true){
        throw new Error('asn-one_DERSerializer Error')
    }
    print(`asn-one_DERSerializer: ${endTime - startTime} ms`)
}

function DERDeserializer_TEST() {
    const serialize = new DERSerializer();

    const asn1Sequence = new Universal.Sequence([
        new Universal.Integer(2024),
        new Universal.Null(), 
        new Universal.PrintableString(TEN_kB), 
        new Universal.PrintableString('an underwater universe where sunlight barely penetrates and darkness reigns supreme.'),
    ]);
    const bufferContainingDEREncodedASN2 = serialize(asn1Sequence);
    const deserialize2 = new DERDeserializer();

    let des;
    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        des = deserialize2(bufferContainingDEREncodedASN2);
    }
    let endTime = Date.now()

    if(des.content.length !== 4){
        throw new Error('asn-one_DERDeserializer Error')
    }
    print(`asn-one_DERDeserializer: ${endTime - startTime} ms`)
}

function Sequence_BER_TEST_01() {
    let ber;
    const asn = new asn1js.Sequence({
        name: "block1",
        value: [
            new asn1js.OctetString({
                name: "block2",
                valueHex: new Uint8Array([0x01, 0x02, 0x03])
            }),
            new asn1js.Null({
                name: "block6"
            }),
            new asn1js.Integer({
                name: "block7",
                optional: true
            }),
        ]
    });

    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        ber = asn.toBER();
    }
    let endTime = Date.now()

    if(ber.byteLength !== 11){
        throw new Error('asn-one_Sequence(toBER) Error')
    }
    print(`asn-one_Sequence(toBER): ${endTime - startTime} ms`)
}

function Sequence_BER_TEST_02() {
    let asnParsed;
    const asn = new asn1js.Sequence({
        name: "block1",
        value: [
            new asn1js.OctetString({
                name: "block2",
                valueHex: new Uint8Array([0x01, 0x02, 0x03])
            }),
            new asn1js.Null({
                name: "block6"
            }),
            new asn1js.Integer({
                name: "block7",
                optional: true
            }),
        ]
    });
    const ber = asn.toBER();

    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        asnParsed = asn1js.fromBER(ber);
    }
    let endTime = Date.now()

    if(asnParsed.offset !== 11){
        throw new Error('asn-one_Sequence(fromBER) Error')
    }
    print(`asn-one_Sequence(fromBER): ${endTime - startTime} ms`)
}

function toBase64_TESE(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        result = toBase64(ONE_KB)
    }
    let endTime = Date.now()

    if(result !== Base64){
        throw new Error('asn-one_toBase64  Error')
    }
    print(`asn-one_toBase64: ${endTime - startTime} ms`)
}

function fromBase64_TESE(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10; i++) {
        result = fromBase64(Base64)
    }
    let endTime = Date.now()

    if(result !== ONE_KB){
        throw new Error('asn-one_fromBase64  Error')
    }
    print(`asn-one_fromBase64: ${endTime - startTime} ms`)
}

function stringToArrayBuffer_TESE(){
    let result;

    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        result = stringToArrayBuffer(ONE_KB)
    }
    let endTime = Date.now()

    if(result.byteLength !== 1024){
        throw new Error('asn-one_stringToArrayBuffer  Error')
    }
    print(`asn-one_stringToArrayBuffer: ${endTime - startTime} ms`)
}

function arrayBufferToString_TESE(){
    const data = new Uint8Array([72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111]);

    let startTime = Date.now()
    let result;
    for (let i = 0; i < 10000; i++) {
        result = arrayBufferToString(data)
    }
    let endTime = Date.now()

    if(result !== 'HelloHelloHelloHelloHelloHelloHelloHelloHello'){
        throw new Error('asn-one_arrayBufferToString Error')
    }
    print(`asn-one_arrayBufferToString: ${endTime - startTime} ms`)
}

function bufferToHexCodes_TESE(){
    const data = new Uint8Array([72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111]);
    let ab = data.buffer.slice(0,data.buffer.byteLength)
    let buffer;

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        buffer = bufferToHexCodes(ab)
    }
    let endTime = Date.now()

    if(buffer !== '48656C6C6F48656C6C6F48656C6C6F48656C6C6F48656C6C6F48656C6C6F48656C6C6F48656C6C6F48656C6C6F'){
        throw new Error('asn-one_bufferToHexCodes Error')
    }
    print(`asn-one_bufferToHexCodes: ${endTime - startTime} ms`)
}

function checkBufferParams_TESE(){
    const baseBlock = {};
    let result;

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = checkBufferParams(baseBlock, new ArrayBuffer(1024), 1, 1);
    }
    let endTime = Date.now()
    
    if(result == false){
        throw new Error('asn-one_checkBufferParams Error')
    }
    print(`asn-one_checkBufferParams: ${endTime - startTime} ms`)
}

function getParametersValue_TESE(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = getParametersValue({ name: 33 }, "name", 'Error')
    }
    let endTime = Date.now()

    if(result == 'Error'){
        throw new Error('asn-one_getParametersValue Error')
    }
    print(`asn-one_getParametersValue: ${endTime - startTime} ms`)
}

function getUTCDate_TESE(){
    const regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$/;
    let result;
    const date = new Date();

    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = getUTCDate(date)
    }
    let endTime = Date.now()
    
    if(!regex.test(result.toISOString())){
        throw new Error('asn-one_getUTCDate  Error')
    }
    print(`asn-one_getUTCDate: ${endTime - startTime} ms`)
}

function isEqualBuffer_TESE(){
    let result;
    const data = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A]);
    let ab = data.buffer.slice(0,data.buffer.byteLength)

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = isEqualBuffer(ab, ab)
    }
    let endTime = Date.now()
    
    if(result == false){
        throw new Error('asn-one_isEqualBuffer  Error')
    }
    print(`asn-one_isEqualBuffer: ${endTime - startTime} ms`)
}

function nearestPowerOf2_TESE(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = nearestPowerOf2(Number.MAX_SAFE_INTEGER)
    }
    let endTime = Date.now()

    if(result !== 53){
        throw new Error('asn-one_nearestPowerOf2  Error')
    }
    print(`asn-one_nearestPowerOf2: ${endTime - startTime} ms`)
}

function padNumber_TESE(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = padNumber(1, 11)
    }
    let endTime = Date.now()

    if(result !== '00000000001'){
        throw new Error('asn-one_padNumber  Error')
    }
    print(`asn-one_padNumber: ${endTime - startTime} ms`)
}

function utilConcatBuf_TESE(){
    let result;
    const data = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A]);
    let ab = data.buffer.slice(0,data.buffer.byteLength)

    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = utilConcatBuf(ab, ab, ab)
    }
    let endTime = Date.now()

    if(result.byteLength !== 30){
        throw new Error('asn-one_utilConcatBuf Error')
    }
    print(`asn-one_utilConcatBuf: ${endTime - startTime} ms`)
}

function utilConcatView_TESE(){
    let result;
    const data = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A]);

    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = utilConcatView(data,data)
    }
    let endTime = Date.now()

    if(result.byteLength !== 20){
        throw new Error('asn-one_utilConcatView Error')
    }
    print(`asn-one_utilConcatView: ${endTime - startTime} ms`)
}

function utilFromBase_TESE(){
    let result;
    let inputBuffer1 = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A];

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = utilFromBase(inputBuffer1, 16)
    }
    let endTime = Date.now()

    if(result !== 2.2301425778841673e+43){
        throw new Error('asn-one_utilFromBase Error')
    }
    print(`asn-one_utilFromBase: ${endTime - startTime} ms`)
}

function utilToBase_TESE(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = utilToBase(Number.MAX_SAFE_INTEGER, 10)
    }
    let endTime = Date.now()

    if(result.byteLength !== 6){
        throw new Error('asn-one_utilToBase Error')
    }
    print(`asn-one_utilToBase: ${endTime - startTime} ms`)
}

function Boolean_TEST(){
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        asn = new asn1js.Boolean({
            value: true,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== true){
        throw new Error('asn-one_Boolean Error')
    }
    print(`asn-one_Boolean: ${endTime - startTime} ms`)
}

function BmpString_TEST(){
    const BmpValue = "s4AahmO&s4AahmO&vi8O0b5n@jcrs4AahmO&vi8O0b5n@jcrSrtExOZd#";
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        asn = new asn1js.BmpString({
            value: BmpValue,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== BmpValue){
        throw new Error('asn-one_BmpString Error')
    }
    print(`asn-one_BmpString: ${endTime - startTime} ms`)
}

function BitString_TEST(){
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.BitString({
            value: buffer
        });
    }
    let endTime = Date.now()

    if(asn.valueBlock.value!== buffer){
        throw new Error('asn-one_BitString Error')
    }
    print(`asn-one_BitString: ${endTime - startTime} ms`)
}

function Integer_BER_TEST(){
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.Integer({
            value: 97196
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed  = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock._valueDec !== 97196){
        throw new Error('asn-one_Integer Error')
    }
    print(`asn-one_Integer_BER: ${endTime - startTime} ms`)
}

function CharacterString_TEST(){
    const testString = ONE_KB;
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.CharacterString({
            value: testString,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== testString){
        throw new Error('asn-one_CharacterString Error')
    }
    print(`asn-one_CharacterString: ${endTime - startTime} ms`)
}

function UniversalString_TEST(){
    const testString = ONE_KB;
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 10; i++) {
        asn = new asn1js.UniversalString({
            value: testString,
        });
    }
    let endTime = Date.now()
    let ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== testString){
        throw new Error('asn-one_UniversalString Error')
    }
    print(`asn-one_UniversalString: ${endTime - startTime} ms`)
}

function Utf8String_TEST(){
    const UTF8String = "Computer science is the study of algorithmic processes, computational machines and computation itself. As a discipline, computer science spans a range of topics from theoretical studies of algorithms, computation and information to the practical issues of implementing computational systems in hardware and software. It is among the natural sciences as it seeks to describe the behavior of certain natural phenomena through both logical reasoning and empirical methods";
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.Utf8String({
            value: UTF8String,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== UTF8String){
        throw new Error('asn-one_Utf8String Error')
    }
    print(`asn-one_Utf8String: ${endTime - startTime} ms`)
}

function DATE_TEST(){
    const dataString = "2024-03-02";
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.DATE({
            value: dataString,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== dataString){
        throw new Error('asn-one_DATE Error')
    }
    print(`asn-one_DATE: ${endTime - startTime} ms`)
}

function DateTime_TEST(){
    const dataTimeString = "2024-03-02 17:30";
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.DateTime({
            value: dataTimeString,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== dataTimeString){
        throw new Error('asn-one_DateTime Error')
    }
    print(`asn-one_DateTime: ${endTime - startTime} ms`)
}

function Duration_TEST(){
    const testString = '1000';
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn  = new asn1js.Duration({
            value: testString,
        });
    }
    let endTime = Date.now()
    const ber  = asn.toBER();
    let asnParsed  = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== testString){
        throw new Error('asn-one_Duration Error')
    }
    print(`asn-one_Duration: ${endTime - startTime} ms`)
}

function GeneralString_TEST(){
    let asn;
    const testString = ONE_KB;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.GeneralString({
            value: testString,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== testString){
        throw new Error('asn-one_GeneralString Error')
    }
    print(`asn-one_GeneralString: ${endTime - startTime} ms`)
}

function GraphicString_TEST(){
    let asn;
    const testString = ONE_KB;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn  = new asn1js.GraphicString({
            value: testString,
        });
    }
    let endTime = Date.now()
    const ber  = asn.toBER();
    let asnParsed  = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== testString){
        throw new Error('asn-one_GraphicString Error')
    }
    print(`asn-one_GraphicString: ${endTime - startTime} ms`)
}

function NumericString_TEST(){
    let asn;
    const numString = ONE_KB_NUMBER_STRING;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.NumericString({
            value: numString,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value !== numString){
        throw new Error('asn-one_NumericString Error')
    }
    print(`asn-one_NumericString: ${endTime - startTime} ms`)
}

function ObjectIdentifier_TEST(){
    let asn;
    const testString = '0.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20';
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.ObjectIdentifier({
            value: testString,
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed  = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value.toString() !== '0.2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20'){
        throw new Error('asn-one_ObjectIdentifier Error')
    }
    print(`asn-one_ObjectIdentifier: ${endTime - startTime} ms`)
}

function OctetString_TEST(){
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        asn = new asn1js.OctetString({
            value: new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A])
        });
    }
    let endTime = Date.now()

    if(asn.valueBlock.value.toString() !== '1,2,3,4,5,6,7,8,9,10'){
        throw new Error('asn-one_OctetString Error')
    }
    print(`asn-one_OctetString: ${endTime - startTime} ms`)
}

function Null_BER_TEST(){
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.Null({
            name: "block2",
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed  = asn1js.fromBER(ber);
    
    if(asnParsed.result.constructor.name !== "Null"){
        throw new Error('asn-one_Null Error')
    }
    print(`asn-one_Null: ${endTime - startTime} ms`)
}

function Sequence_BER_TEST(){
    let asn;
    let startTime = Date.now()
    for (let i = 0; i < 1000; i++) {
        asn = new asn1js.Sequence({
            name: "block1",
            value: [
                new asn1js.OctetString({
                    name: "block2",
                    valueHex: new Uint8Array([0x01, 0x02, 0x03])
                }),
                new asn1js.Sequence({
                    name: "block3",
                    value: [
                        new asn1js.Boolean({
                            name: "block4",
                            value: true
                        }),
                        new asn1js.ObjectIdentifier({
                            name: "block5",
                            value: "1.2.3.4.5"
                        }),
                    ]
                }),
                new asn1js.Null({
                    name: "block6"
                }),
                new asn1js.Integer({
                    name: "block7",
                    optional: true
                }),
            ]
        });
    }
    let endTime = Date.now()
    const ber = asn.toBER();
    let asnParsed  = asn1js.fromBER(ber);

    if(asnParsed.result.valueBlock.value.length !== 4){
        throw new Error('asn-one_Sequence Error')
    }
    print(`asn-one_Sequence: ${endTime - startTime} ms`)
}

function Switch() {
    Sequence_TEST()
    Integer_TEST()
    Null_TEST()
    Bool_TEST()
    PrintableString_TEST()
    JSONSerializer_TEST()
    JSONDeserializer_TEST()
    DERSerializer_TEST()
    DERDeserializer_TEST()
    Sequence_BER_TEST_01()
    Sequence_BER_TEST_02()
    toBase64_TESE()
    fromBase64_TESE()
    stringToArrayBuffer_TESE()
    arrayBufferToString_TESE()
    bufferToHexCodes_TESE()
    checkBufferParams_TESE()
    getParametersValue_TESE()
    getUTCDate_TESE()
    isEqualBuffer_TESE()
    nearestPowerOf2_TESE()
    padNumber_TESE()
    utilConcatBuf_TESE()
    utilConcatView_TESE()
    utilFromBase_TESE()
    utilToBase_TESE()
    Boolean_TEST()
    BmpString_TEST()
    BitString_TEST()
    Integer_BER_TEST()
    CharacterString_TEST()
    UniversalString_TEST()
    Utf8String_TEST()
    DATE_TEST()
    DateTime_TEST()
    Duration_TEST()
    GeneralString_TEST()
    GraphicString_TEST()
    NumericString_TEST()
    ObjectIdentifier_TEST()
    OctetString_TEST()
    Null_BER_TEST()
    Sequence_BER_TEST()
}
let loopCountForPreheat = 1;
for (let i = 0; i < loopCountForPreheat; i++) {
    Switch()
}

ArkTools.waitAllJitCompileFinish();

Switch()